import os
import sys
import shutil
import zipfile
import fitz
from datetime import datetime
from PyQt6.QtCore import QThread, pyqtSignal

class PDFConverter(QThread):
    progress_updated = pyqtSignal(int, str)
    conversion_finished = pyqtSignal(str, str)  # html_path, output_dir
    error_occurred = pyqtSignal(str)

    def __init__(self, pdf_path, output_dir):
        super().__init__()
        self.pdf_path = pdf_path
        self.output_dir = output_dir
        self.images_dir = os.path.join(output_dir, 'images')
        self.running = True
        self.temp_dir = None

    def run(self):
        try:
            # Create a timestamped output directory
            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
            self.temp_dir = os.path.join(self.output_dir, f'pdf_export_{timestamp}')
            self.images_dir = os.path.join(self.temp_dir, 'images')
            
            # Create output directories
            os.makedirs(self.images_dir, exist_ok=True)
            
            # Open the PDF
            pdf_document = fitz.open(self.pdf_path)
            total_pages = len(pdf_document)
            
            # Convert each page to image
            image_paths = []
            for page_num in range(total_pages):
                if not self.running:
                    self._cleanup()
                    return
                    
                page = pdf_document[page_num]
                zoom = 2  # Higher zoom for better quality
                mat = fitz.Matrix(zoom, zoom)
                pix = page.get_pixmap(matrix=mat, alpha=False)
                
                # Save image
                img_path = os.path.join(self.images_dir, f'page_{page_num + 1:03d}.jpg')
                pix.save(img_path)
                image_paths.append(img_path)
                
                # Update progress
                progress = int((page_num + 1) / total_pages * 90)  # Reserve 10% for HTML generation
                self.progress_updated.emit(progress, f'Processing page {page_num + 1}/{total_pages}...')
            
            # Generate HTML
            from .html_generator import HTMLGenerator
            html_generator = HTMLGenerator(self.images_dir)
            html_path = html_generator.generate(
                image_paths,
                os.path.basename(self.pdf_path),
                self.temp_dir
            )
            
            # Create zip file
            zip_path = self._create_zip(html_path)
            
            # Update progress
            self.progress_updated.emit(100, 'Conversion completed successfully!')
            self.conversion_finished.emit(html_path, self.temp_dir)
            
        except Exception as e:
            self.error_occurred.emit(str(e))
        finally:
            if 'pdf_document' in locals():
                pdf_document.close()

    def _create_zip(self, html_path):
        """
        Create a ZIP archive containing all output files
        
        Args:
            html_path (str): Path to the generated HTML file
            
        Returns:
            str: Path to the created ZIP file
        """
        try:
            if not os.path.exists(html_path):
                raise FileNotFoundError(f"HTML file not found: {html_path}")
                
            # Create ZIP file in the parent directory of the output
            output_dir = os.path.dirname(html_path)
            zip_filename = os.path.splitext(os.path.basename(html_path))[0] + '.zip'
            zip_path = os.path.join(os.path.dirname(output_dir), zip_filename)
            
            with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
                # Add HTML file
                zipf.write(html_path, os.path.basename(html_path))
                
                # Add images directory
                images_dir = os.path.join(output_dir, 'images')
                if os.path.exists(images_dir):
                    for root, _, files in os.walk(images_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arcname = os.path.relpath(file_path, output_dir)
                            zipf.write(file_path, arcname)
                
                # Add any additional files (like image_paths.json)
                for file in os.listdir(output_dir):
                    if file.endswith('.json'):
                        file_path = os.path.join(output_dir, file)
                        zipf.write(file_path, os.path.basename(file_path))
            
            return zip_path
            
        except Exception as e:
            self.error_occurred.emit(f"Failed to create ZIP archive: {str(e)}")
            raise
    
    def stop(self):
        """Stop the conversion process"""
        self.running = False